/*
 * Licensed under the GNU General Public License version 2 with exceptions. See
 * LICENSE file in the project root for full license information
 */

/** \file
 * \brief
 * ESC hardware layer functions for LAN9252 through BCM2835 SPI on Raspberry PI.
 *
 * Function to read and write commands to the ESC. Used to read/write ESC
 * registers and memory.
 */
#include "esc.h"
#include "esc_hw.h"
#include <string.h>
#include <stdlib.h>

#define BIT(x)  (1U << (x))
#define ESC_BASE    0x60000000

/** ESC read function used by the Slave stack.
 *
 * @param[in]   address     = address of ESC register to read
 * @param[out]  buf         = pointer to buffer to read in
 * @param[in]   len         = number of bytes to read
 */
void ESC_read (uint16_t address, void *buf, uint16_t len)
{
    switch(len)
    {
    case 4:
        *(uint32_t*)buf = *(volatile uint32_t*)(ESC_BASE + address);
        break;
    case 2:
        *(uint16_t*)buf = *(volatile uint16_t*)(ESC_BASE + address);
        break;
    case 1:
    default:
        memcpy(buf,(void*)(ESC_BASE+address),len);
        break;
    }
    ESCvar.ALevent = *(volatile uint32_t*)(ESC_BASE + ESCREG_ALEVENT);
    ESCvar.ALevent = etohs(ESCvar.ALevent);
}

/** ESC write function used by the Slave stack.
 *
 * @param[in]   address     = address of ESC register to write
 * @param[out]  buf         = pointer to buffer to write from
 * @param[in]   len         = number of bytes to write
 */
void ESC_write (uint16_t address, void *buf, uint16_t len)
{
    switch(len)
    {
    case 4:
        *(volatile uint32_t*)(ESC_BASE + address) = *(uint32_t*)buf;
        break;
    case 2:
        *(volatile uint16_t*)(ESC_BASE + address) = *(uint16_t*)buf;
        break;
    case 1:
    default:
        memcpy((void*)(ESC_BASE+address),buf,len);
        break;
    }
    ESCvar.ALevent = *(volatile uint32_t*)(ESC_BASE + ESCREG_ALEVENT);
    ESCvar.ALevent = etohs(ESCvar.ALevent);
}

void ESC_reset (void)
{

}

void ESC_init (const esc_cfg_t * config)
{
    uint32_t value;
    // Set AL event mask
    value = (ESCREG_ALEVENT_CONTROL |
             ESCREG_ALEVENT_SMCHANGE |
             ESCREG_ALEVENT_SM0 |
             ESCREG_ALEVENT_SM1 |
             ESCREG_ALEVENT_DC_SYNC0 );
    ESC_ALeventmaskwrite(value);
}

void ESC_interrupt_enable (uint32_t mask)
{
}

void ESC_interrupt_disable (uint32_t mask)
{
}
